#include "./FUdpExample.h"
#include "Common/UdpSocketBuilder.h"


FUdpExample::~FUdpExample()
{
	Close();
}

FUdpExample::FUdpExample()
{
	bIsReceiving = false;
	ListenThread = nullptr;
	DefaultSendTargetIp = TEXT("127.0.0.1");
	DefaultSendTargetPort = REMOTE_PORT;
	UdpSocket = FUdpSocketBuilder(TEXT("FUdpSocketBuilder")).AsReusable().WithBroadcast().AsBlocking();
	auto LocalInternetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	bool bIsValid = false;
	LocalInternetAddr->SetIp(TEXT("127.0.0.1"), bIsValid);
	LocalInternetAddr->SetPort(LOCAL_PORT);
	UdpSocket->Bind(*LocalInternetAddr);
	SetSendDefaultTargetAddr();
	StartListen();
}


void FUdpExample::SetSendDefaultTargetAddr(const FString& Ip, const int32 Port)
{
	DefaultSendTargetIp = Ip;
	DefaultSendTargetPort = Port;
}

void FUdpExample::SendMsg(const FString& Msg, const FString& Ip, const int32 Port) const
{
	if (!UdpSocket)
	{
		UE_LOG(LogTemp, Warning, TEXT("Udp 服务还没有创建成功，无法发送消息！！！"));
		return;
	}
	auto InternetAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	bool bIsValid = false;
	InternetAddr->SetIp(*Ip, bIsValid);
	if (!bIsValid)
	{
		UE_LOG(LogTemp, Warning, TEXT("%s 是无效的IP地址，发送消息失败！！！"), *Ip);
		return;
	}
	InternetAddr->SetPort(Port);
	FTCHARToUTF8 Data(*Msg, Msg.Len());
	TArray<uint8> Buffer;
	Buffer.Append(reinterpret_cast<const uint8*>(Data.Get()), Data.Length());
	int32 WriteSize;
	UdpSocket->SendTo(Buffer.GetData(), Buffer.Num(), WriteSize, *InternetAddr);
}

void FUdpExample::SendMsg(const FString& Msg) const
{
	SendMsg(Msg, DefaultSendTargetIp, DefaultSendTargetPort);
}

void FUdpExample::StartListen()
{
	if (bIsReceiving) return;
	bIsReceiving = true;
	ListenThread = FRunnableThread::Create(this, TEXT("FUdpExample Thread"));
}


uint32 FUdpExample::Run()
{
	uint8* Buffer = new uint8[UDP_BUFFER_SIZE];
	int32 ReadSize;
	while (bIsReceiving && UdpSocket)
	{
		UdpSocket->Recv(Buffer, UDP_BUFFER_SIZE, ReadSize);
		if (ReadSize > 0)
		{
			FUTF8ToTCHAR UTC(reinterpret_cast<const ANSICHAR*>(Buffer), ReadSize);
			FString Msg(UTC.Length(), UTC.Get());
			UE_LOG(LogTemp, Warning, TEXT("接收到 UDP 消息：%s"), *Msg);
		}
	}
	return 0;
}

void FUdpExample::Close()
{
	if (!bIsReceiving) return;
	bIsReceiving = false;
	UE_LOG(LogTemp, Warning, TEXT("Closing FUdpExample"));
	if (UdpSocket)
	{
		UdpSocket->Close();
		ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(UdpSocket);
		UdpSocket = nullptr;
	}
	if (ListenThread)
	{
		ListenThread->Kill();
		delete ListenThread;
		ListenThread = nullptr;
	}
}
